<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,minimum-scale=1,maximum-scale=1">


<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />



  <meta name="description" content="如何将DOM转换为virtual DOM?"/>




  <meta name="keywords" content="Vue," />





  <link rel="alternate" href="/default" title="刘粉丝来了">






<link rel="canonical" href="http://yoursite.com/2020/04/09/virtual DOM/"/>


<meta name="description" content="virtual DOM的优点是什么？ 为什么需要virtual DOM？ 保证性能下限，以及跨平台  无需手动操作DOM，只需要写好 View-Model 的代码逻辑，框架会根据虚拟DOM和数据双向绑定，帮我们以可预期的方式更新视图，极大提高我们的开发效率；  虚拟DOM的核心思想是：对复杂的文档DOM结构，提供一种方便的工具，进行最小化的DOM操作，这句话，也许过于抽象，却基本概况了虚拟DOM的">
<meta property="og:type" content="article">
<meta property="og:title" content="如何将DOM转换为virtual DOM?">
<meta property="og:url" content="http://yoursite.com/2020/04/09/virtual%20DOM/index.html">
<meta property="og:site_name" content="刘粉丝来了">
<meta property="og:description" content="virtual DOM的优点是什么？ 为什么需要virtual DOM？ 保证性能下限，以及跨平台  无需手动操作DOM，只需要写好 View-Model 的代码逻辑，框架会根据虚拟DOM和数据双向绑定，帮我们以可预期的方式更新视图，极大提高我们的开发效率；  虚拟DOM的核心思想是：对复杂的文档DOM结构，提供一种方便的工具，进行最小化的DOM操作，这句话，也许过于抽象，却基本概况了虚拟DOM的">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://120.79.197.3:8006/api/image/7b29f7097f2c905a60840faff115afe6.png">
<meta property="article:published_time" content="2020-04-09T09:03:12.000Z">
<meta property="article:modified_time" content="2020-04-11T09:00:16.298Z">
<meta property="article:author" content="刘粉丝来了">
<meta property="article:tag" content="Vue">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://120.79.197.3:8006/api/image/7b29f7097f2c905a60840faff115afe6.png">


<link rel="stylesheet" type="text/css" href="/css/style.css?v=1.1" />
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet'>





<script type="text/javascript">
  var themeConfig = {
    fancybox: {
      enable: false
    },
  };
</script>




  



    <title> 如何将DOM转换为virtual DOM? - 刘粉丝来了 </title>
  <meta name="generator" content="Hexo 4.2.0"></head>

  <body>
    <div id="page">
      <header id="masthead"><div class="site-header-inner">
    <h1 class="site-title">
        <a href="/." class="logo">刘粉丝来了</a>
    </h1>

    <nav id="nav-top">
        
            <ul id="menu-top" class="nav-top-items">
                
                    <li class="menu-item">
                        <a href="/">
                            
                            
                                Home
                            
                        </a>
                    </li>
                
                    <li class="menu-item">
                        <a href="/archives">
                            
                            
                                Archives
                            
                        </a>
                    </li>
                
                    <li class="menu-item">
                        <a href="/tags">
                            
                            
                                Tags
                            
                        </a>
                    </li>
                
                    <li class="menu-item">
                        <a href="/about">
                            
                            
                                About
                            
                        </a>
                    </li>
                
            </ul>
        
  </nav>
</div>

      </header>
      <div id="content">
        
    <div id="primary">
        
  <article class="post">
    <header class="post-header">
      <h1 class="post-title">
        
          如何将DOM转换为virtual DOM?
        
      </h1>

      <time class="post-time">
          4月 09 2020
      </time>
    </header>



    
            <div class="post-content">
            <h5 id="virtual-DOM的优点是什么？-为什么需要virtual-DOM？"><a href="#virtual-DOM的优点是什么？-为什么需要virtual-DOM？" class="headerlink" title="virtual DOM的优点是什么？ 为什么需要virtual DOM？"></a>virtual DOM的优点是什么？ 为什么需要virtual DOM？</h5><ol>
<li><p>保证性能下限，以及跨平台</p>
</li>
<li><p>无需手动操作DOM，只需要写好 View-Model 的代码逻辑，框架会根据虚拟DOM和数据双向绑定，帮我们以可预期的方式更新视图，极大提高我们的开发效率；</p>
</li>
<li><p>虚拟DOM的核心思想是：对复杂的文档DOM结构，提供一种方便的工具，进行最小化的DOM操作，这句话，也许过于抽象，却基本概况了虚拟DOM的设计思想</p>
</li>
</ol>
<h3 id="接下来我们来简单的模拟vue是如何生成虚拟DOM的，超简版！！！"><a href="#接下来我们来简单的模拟vue是如何生成虚拟DOM的，超简版！！！" class="headerlink" title="接下来我们来简单的模拟vue是如何生成虚拟DOM的，超简版！！！"></a>接下来我们来简单的模拟vue是如何生成虚拟DOM的，超简版！！！</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">&lt;div id=<span class="string">"root"</span>&gt; </span><br><span class="line">    &lt;p&gt;韩梅梅的咖啡机&lt;<span class="regexp">/p&gt;</span></span><br><span class="line"><span class="regexp">    &lt;p&gt;李雷的致富之路&lt;/</span>p&gt;</span><br><span class="line">&lt;<span class="regexp">/div&gt;</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">const app = new Vue(&#123;</span></span><br><span class="line"><span class="regexp">    el:'#root',</span></span><br><span class="line"><span class="regexp">    data:&#123;</span></span><br><span class="line"><span class="regexp">        name:'吴亦凡',</span></span><br><span class="line"><span class="regexp">        age:22</span></span><br><span class="line"><span class="regexp">    &#125;</span></span><br><span class="line"><span class="regexp">&#125;)</span></span><br></pre></td></tr></table></figure>

<p>是否有点眼熟呢！ 没错 在使用<code>Vue</code>搭建的脚手架里面的<code>main.js</code>文件里面包含了这个代码块,接下来我们需要对我们new出来的<code>Vue</code>对象进行处理</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Vue</span> (<span class="params"> options </span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>._template = <span class="built_in">document</span>.querySelector( options.el );</span><br><span class="line"></span><br><span class="line">    <span class="keyword">let</span> AST  =  getVNode( <span class="keyword">this</span>._template );</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>将传进来的根元素存到对象实例上<br>getVNode 将DOM转为virtual DOM</p>
<blockquote>
<p>class VNode 基于这个类进行实现</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">VNode</span> </span>&#123;</span><br><span class="line">    <span class="keyword">constructor</span>( tag, data, value, type ) &#123;</span><br><span class="line">        <span class="keyword">this</span>.tag = tag &amp;&amp; tag.toLowerCase();</span><br><span class="line">        <span class="keyword">this</span>.data = data;</span><br><span class="line">        <span class="keyword">this</span>.value = value;</span><br><span class="line">        <span class="keyword">this</span>.type = type;</span><br><span class="line">        <span class="keyword">this</span>.children = [];</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    appChildren( value ) &#123;</span><br><span class="line">        <span class="keyword">this</span>.children.push( value );</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><em>tag 代表标签</em></p>
<p><em>data 代表属性</em> </p>
<p><em>value 代表值</em></p>
<p><em>type 代表类型</em></p>
<p><em>children 代表我的子级</em></p>
<pre><code class="javascript"><span class="function"><span class="keyword">function</span> <span class="title">getVNode</span>(<span class="params"> node </span>) </span>{
    <span class="keyword">let</span> nodeType = node.nodeType;
    <span class="keyword">let</span> _vnode = <span class="literal">null</span>;

    <span class="keyword">if</span> ( nodeType === <span class="number">1</span> ) {
        <span class="keyword">let</span> nodeName = node.nodeName;
        <span class="keyword">let</span> attrs = node.attributes;
        <span class="keyword">let</span> _attrObj = {};
        <span class="keyword">for</span> ( <span class="keyword">let</span> i = <span class="number">0</span>; i &lt; attrs.length; i++ ) {
            _attrObj[ attrs[i].nodeName ] = attrs[i].nodeValue;
        }

        _vnode = <span class="keyword">new</span> VNode( nodeName, _attrObj, <span class="literal">undefined</span>, nodeType );

        <span class="keyword">let</span> childNodes = node.childNodes;
        <span class="keyword">for</span>( <span class="keyword">let</span> i = <span class="number">0</span>; i &lt; childNodes.length; i++ ) {
            _vnode.appChildren( getVNode( childNodes[i] ) )
        }

    } <span class="keyword">else</span> <span class="keyword">if</span> ( nodeType === <span class="number">3</span> ) {
        _vnode = <span class="keyword">new</span> VNode( <span class="literal">undefined</span>, <span class="literal">undefined</span>, node.nodeValue, nodeType )
    }

    <span class="keyword">return</span> _vnode;
}</code></pre>
<p>第一步的要点是先理解<code>nodeType</code>代表的是什么，<code>nodeType</code>为1则代表元素， <code>nodeType</code>为3则代表文本， 现在我们剖析为1的情况下反过来再看看<code>class VNode</code>的构造函数需要的是什么？ 需要什么我们就从DOM身上拿, <code>nodeName</code>代表标签 <code>_attrObj</code>代表属性 <code>nodeType</code>代表类型 元素身上是没有文本的所以<code>value</code>这个字段直接传<code>undefined</code> 接着把new出来的对象实例赋给<code>_vnode</code> 紧接着拿出当前元素的所有子元素 进行遍历递归写入<code>_vnode</code>中的<code>children</code> 至此元素的处理结束了，现在进入为 3 的情况下 既然是文本肯定没有标签以及属性所以直接传<code>undefined</code> 值则用<code>node.nodeValue</code>取，同样<code>nodeType</code>也代表类型，每次递归进来会对不同类型做不同的处理。</p>
<blockquote>
<p>以下则是转换结果</p>
</blockquote>
<p><img src="http://120.79.197.3:8006/api/image/7b29f7097f2c905a60840faff115afe6.png" alt="虚拟DOM" title="virtual DOM"></p>
<blockquote>
<p>下一节预告: virtual DOM如何与数据结合？ 如何将virtual DOM反转回DOM？<br>看到这里文章也已经结束了，希望对您有所帮助! </p>
</blockquote>

            </div>
          

    
      <footer class="post-footer">
		
		<div class="post-tags">
		  
			<a href="/tags/Vue/">Vue</a>
		  
		</div>
		

        
        
  <nav class="post-nav">
    
      <a class="prev" href="/2020/04/10/inversion/">
        <i class="iconfont icon-left"></i>
        <span class="prev-text nav-default">virtual DOM如何与数据结合？ 如何将virtual DOM反转回DOM？</span>
        <span class="prev-text nav-mobile">上一篇</span>
      </a>
    
    
      <a class="next" href="/2020/04/08/hello-world/">
        <span class="next-text nav-default">欢迎来到 刘粉丝 的前端自习室</span>
        <span class="prev-text nav-mobile">下一篇</span>
        <i class="iconfont icon-right"></i>
      </a>
    
  </nav>

        
  <div class="comments" id="comments">
    
  </div>


      </footer>
    
  </article>


    </div>

      </div>

      <footer id="colophon"><script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
</script>
<span class="copyright-year" style="width:100%; display:flex; justify-content: space-between;">
    <span>
        
        &copy;
    
        2014 -
    
    2020
    <span class="footer-author">刘粉丝来了.</span>
    <span class="power-by">
        由 <a class="hexo-link" href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a> and <a class="theme-link" href="https://github.com/frostfan/hexo-theme-polarbear" target="_blank" rel="noopener">Polar Bear</a> 强力驱动
    </span>
    </span>
    <span id="busuanzi_container_site_pv">
        本站总访问量<span id="busuanzi_value_site_pv" style="color:red">24280</span>次
    </span>
</span>



      </footer>

      <div class="back-to-top" id="back-to-top">
        <i class="iconfont icon-up"></i>
      </div>
    </div>
    


    




  
    <script type="text/javascript" src="/lib/jquery/jquery-3.1.1.min.js"></script>
  

  

    <script type="text/javascript" src="/js/src/theme.js?v=1.1"></script>
<script type="text/javascript" src="/js/src/bootstrap.js?v=1.1"></script>


  </body>
</html>
